﻿using System.ComponentModel;
using System.ComponentModel.Design;
using System.Reflection;
using C4F.VistaP2P.Win.Chat;
using C4F.VistaP2P.Win.File;
using C4F.VistaP2P.Win.Picture;
using C4F.VistaP2P.Win.Media;


namespace C4F.VistaP2P.Win.NetworkADV
{
    public class NetworkDesignerActionListADV : DesignerActionList
    {
        /// <summary>
        /// constructor that automatically displays hte smart tag panel.
        /// </summary>
        /// <param name="component"></param>
        public NetworkDesignerActionListADV(IComponent component)
            : base(component)
        {

            // Automatically display smart tag panel when
            // design-time component is dropped onto the
            // Windows Forms Designer
            this.AutoShow = true;
        }

        /// <summary>
        /// Returns the list of items to display in the smart tag.
        /// </summary>
        /// <returns>the list of items to display in the smart tag.</returns>
        public override DesignerActionItemCollection GetSortedActionItems()
        {

            // Create list to store designer action items
            DesignerActionItemCollection actionItems = new DesignerActionItemCollection();


            //// Add Design category header text
            actionItems.Add(new DesignerActionHeaderItem("P2P Controls"));

            // Add Design category descriptive label
            actionItems.Add(
              new DesignerActionTextItem(
                "Properties that affect which controls the Network Manager Component uses.",
                "Design"));


            actionItems.Add(
             new DesignerActionPropertyItem(
             "Audio",
             "Audio Control",
             GetCategory(this.NetworkControlADV, "Audio"),
             GetDescription(this.NetworkControlADV, "Audio")));


            actionItems.Add(
              new DesignerActionPropertyItem(
                "Chat",
                "Chat Control",
                GetCategory(this.NetworkControlADV, "Chat"),
                GetDescription(NetworkControlADV, "Chat")));

            actionItems.Add(
             new DesignerActionPropertyItem(
               "File",
               "File Control",
               GetCategory(this.NetworkControlADV, "File"),
               GetDescription(this.NetworkControlADV, "File")));



            actionItems.Add(
             new DesignerActionPropertyItem(
               "Picture",
               "Picture Control",
               GetCategory(this.NetworkControlADV, "Picture"),
               GetDescription(this.NetworkControlADV, "Picture")));

            actionItems.Add(
             new DesignerActionPropertyItem(
                "Video",
                "Video Control",
                GetCategory(this.NetworkControlADV, "Video"),
                GetDescription(this.NetworkControlADV, "Video")));


            // Return action list to design time item
            return actionItems;
        }

        /// <summary>
        /// Gets or sets the media control that the network manager should use.
        /// </summary>
        public MediaControl Audio
        {
            get { return this.NetworkControlADV.Audio; }
            set { SetProperty("Audio", value); }
        }


        /// <summary>
        /// Gets or sets the chat control that the network manager should use.
        /// </summary>
        public ChatControl Chat
        {
            get { return this.NetworkControlADV.Chat; }
            set { SetProperty("Chat", value); }
        }

        /// <summary>
        /// Gets or sets the file control that the network manager should use.
        /// </summary>
        public FileControl File
        {
            get { return this.NetworkControlADV.File; }
            set { SetProperty("File", value); }
        }

        /// <summary>
        /// Gets or sets the picture control that the network manager should use.
        /// </summary>
        public PictureControl Picture
        {
            get { return this.NetworkControlADV.Picture; }
            set { SetProperty("Picture", value); }
        }


        /// <summary>
        /// Gets or sets the video control that the network manager should use.
        /// </summary>
        public MediaControl Video
        {
            get { return this.NetworkControlADV.Video; }
            set { SetProperty("Video", value); }
        }


        
        /// <summary>
        /// Helper property to acquire a NetworkControlADV reference
        /// </summary>
        private NetworkManagerADV NetworkControlADV
        {
            get { return (NetworkManagerADV)this.Component; }
        }

        
        /// <summary>
        /// Helper method to safely set a component’s property
        /// </summary>
        /// <param name="propertyName">the property to set</param>
        /// <param name="value">the value to set</param>
        private void SetProperty(string propertyName, object value)
        {
            // Get property
            PropertyDescriptor property = TypeDescriptor.GetProperties(this.NetworkControlADV)[propertyName];
            // Set property value
            property.SetValue(this.NetworkControlADV, value);
        }

        /// <summary>
        /// gets the catagory string from a property.
        /// </summary>
        /// <param name="source">the control to get the property from</param>
        /// <param name="propertyName">the property to get</param>
        /// <returns>the string from a  property.</returns>
        private static string GetCategory(object source, string propertyName)
        {
            PropertyInfo property = source.GetType().GetProperty(propertyName);
            CategoryAttribute attribute = (CategoryAttribute)property.GetCustomAttributes(typeof(CategoryAttribute), false)[0];
            if (attribute == null) return null;
            return attribute.Category;
        }

        /// <summary>
        /// Helper method to return the Description string from a
        /// DescriptionAttribute assigned to a property exposed by 
        /// the specified object 
        /// </summary>
        /// <param name="source">the control to get the source from</param>
        /// <param name="propertyName">the property name to get the description from</param>
        /// <returns>the description from the requested property.</returns>
        private static string GetDescription(object source, string propertyName)
        {
            PropertyInfo property = source.GetType().GetProperty(propertyName);
            DescriptionAttribute attribute = (DescriptionAttribute)property.GetCustomAttributes(typeof(DescriptionAttribute), false)[0];
            if (attribute == null) return null;
            return attribute.Description;
        }
    }
}
